//
//  DateExtension.swift
//  WalkNovel
//
//  Created by Kevin on 2023/7/4.
//

import UIKit
import MapKit

extension Date {
    /// 获取当前 秒级 时间戳 - 10位
    var timeDate: Int {
        let timeInterval: TimeInterval = self.timeIntervalSince1970
        return Int(timeInterval)
    }
    
    /// 获取当前 秒级 时间戳 - 10位
    var timeStamp: String {
        let timeInterval: TimeInterval = self.timeIntervalSince1970
        let timeStamp = Int(timeInterval)
        return "\(timeStamp)"
    }
    
    /// 获取当前 毫秒级 时间戳 - 13位
    var milliStamp: String {
        let timeInterval: TimeInterval = self.timeIntervalSince1970
        let millisecond = CLongLong(round(timeInterval * 1000))
        return "\(millisecond)"
    }
    
    func wn_day(_ d: String = "dd") -> String {
        let format = DateFormatter()
        format.dateFormat = d
        return format.string(from: self)
    }
    
    func wn_month(_ m: String = "M") -> String {
        let format = DateFormatter()
        format.dateFormat = m
        return format.string(from: self)
    }
    
    func wn_mmonth(_ m: String = "MM") -> String {
        let format = DateFormatter()
        format.dateFormat = m
        return format.string(from: self)
    }
    
    func wn_year(_ y: String = "y") -> String {
        let format = DateFormatter()
        format.dateFormat = y
        return format.string(from: self)
    }
    
    func wn_hour(_ y: String = "H") -> String {
        let format = DateFormatter()
        format.dateFormat = y
        return format.string(from: self)
    }
    
    func wn_minute(_ y: String = "m") -> String {
        let format = DateFormatter()
        format.dateFormat = y
        return format.string(from: self)
    }
    
    func wn_second(_ y: String = "s") -> String {
        let format = DateFormatter()
        format.dateFormat = y
        return format.string(from: self)
    }
    
    func wn_toDate(_ d: String = "yyyy/MM/dd") -> String {
        let format = DateFormatter()
        format.dateFormat = d
        return format.string(from: self)
    }
    
    func wn_toTimeDate(_ y: String = "yyyy/MM/dd HH:mm") -> String {
        let format = DateFormatter()
        format.dateFormat = y
        return format.string(from: self)
    }
    
    func wn_toSecondDate(_ y: String = "yyyy/MM/dd HH:mm:ss") -> String {
        let format = DateFormatter()
        format.dateFormat = y
        return format.string(from: self)
    }
    
    func wn_weekday() -> String {
        let weekDays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
        let calendar = NSCalendar.init(calendarIdentifier: .gregorian)
        let timeZone = NSTimeZone.init(name: "Asia/Shanghai")
        calendar?.timeZone = timeZone! as TimeZone
        let calendarUnit = NSCalendar.Unit.weekday
        let theComponents = calendar?.components(calendarUnit, from: self)
        return weekDays[(theComponents?.weekday)!-1]
    }
}

class WNAnnotationView: MKAnnotationView {

    static let lineWidth: CGFloat = 2
    static let pinSize = CGSize(width: 30, height: 37)
    static let pinImage: UIImage = image(with: .blue)

    let button: UIButton = UIButton(type: .custom)

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        image = Self.pinImage
        centerOffset = CGPoint(x: 0, y: -Self.pinSize.height / 2)

        configure(for: annotation)
        configureButton()
    }
        
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override var annotation: MKAnnotation? {
        didSet {
            configure(for: annotation)
        }
    }
    
    // this is required for a tap on the callout/button below the annotation view to be recognized

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard let hitView = super.hitTest(point, with: event) else {
            let pointInButton = convert(point, to: button)
            return button.hitTest(pointInButton, with: event)
        }
        return hitView
    }

    func configure(for annotation: MKAnnotation?) {
        canShowCallout = false
        button.setTitle(annotation?.title ?? "Unknown", for: .normal)

        // if you were also doing clustering, you do that configuration here ...
    }

    func configureButton() {
        addSubview(button)

        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: centerXAnchor),
            button.topAnchor.constraint(equalTo: bottomAnchor, constant: 20)
        ])

        button.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)
    }

    /// Function to create pin image of the desired color
    ///
    /// You could obviously just create an pre-rendered image in your asset collection,
    /// but I find it just as easy to render them programmatically.

    static func image(with color: UIColor) -> UIImage {
        UIGraphicsImageRenderer(size: pinSize).image { _ in
            let bounds = CGRect(origin: .zero, size: pinSize)
            let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
            let r = rect.width / 2
            let h = rect.height - r
            let theta = acos(r / h)
            let center = CGPoint(x: rect.midX, y: rect.midX)
            let path = UIBezierPath(arcCenter: center, radius: r, startAngle: .pi / 2 - theta, endAngle: .pi / 2 + theta, clockwise: false)
            path.addLine(to: CGPoint(x: rect.midX, y: rect.maxY))
            path.lineWidth = lineWidth
            path.close()

            color.setFill()
            path.fill()
            UIColor.white.setStroke()
            path.stroke()

            let path2 = UIBezierPath(arcCenter: center, radius: r / 3, startAngle: 0, endAngle: .pi * 2, clockwise: true)
            UIColor.white.setFill()
            path2.fill()
        }
    }

    @objc func didTapButton(_ sender: Any) {
        if let mapView = mapView, let delegate = mapView.delegate {
            delegate.mapView?(mapView, annotationView: self, calloutAccessoryControlTapped: button)
        }
    }
    var mapView: MKMapView? {
        var view = superview
        while view != nil {
            if let mapView = view as? MKMapView { return mapView }
            view = view?.superview
        }
        return nil
    }
}
